//
//  AFAppDotNetAPIClient.m
//  NTWK
//
//  Created by 张良 on 15/10/26.
//  Copyright © 2015年 ZhuJia. All rights reserved.
//

#import "AFAppDotNetAPIClient.h"
#define IS_SUCCESS @"is_success" //验证该返回数据是否正确
#define ERROR @"error"           //错误
#define ERROR_CODE @"error_code" //错误编号
#define ERROR_MESS @"error_mess" //错误信息
#define DATA @"data"             //数据列表

@implementation AFAppDotNetAPIClient

static NSString * const AFAppDotNetAPIBaseURLString = @"http://www.zl.apptest/MyApplications/HostTest/index.php/api/example/";
static NSString * const AFAppDotNetAPIAuthorizationURLString = @"http://192.168.31.160/appAPI/v1/api/login";

+ (instancetype)sharedClient {
    static AFAppDotNetAPIClient *_sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedClient = [[AFAppDotNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:AFAppDotNetAPIBaseURLString]];
        _sharedClient.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
        _sharedClient.logArr = [NSMutableArray arrayWithCapacity:0];
    });
    
    return _sharedClient;
}

-(void)uploadFile:(NSDictionary *)parameters Url:(NSString *)url Files:(NSArray *)files Result:(void (^)(id result_data, id progress, ApiStatus result_status))result Progress:(void (^)(CGFloat progress))progress {
    
    NSProgress *api_progress = nil;
#ifndef TARGET_IPHONE_SIMULATOR
    if (![NetworkHelper isNetWorkReachable])
    {
        
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedString(@"Please check your network connection is correct", @"请检查您的网络连接是否正确") forKey:NSLocalizedDescriptionKey];
        NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:eJsonNil userInfo:userInfo];
        result(error,api_progress,ApiStatusNetworkNotReachable);
        
    } else {
#endif
        NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
            
            [files enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                [formData appendPartWithFileURL:[NSURL fileURLWithPath:[obj objectForKey:@"file_url"]]
                                           name:[obj objectForKey:@"name"]
                                       fileName:[obj objectForKey:@"file_name"]
                                       mimeType:[obj objectForKey:@"mime_type"]
                                          error:nil];
            }];
            
        } error:nil];
        
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"file_down_identifer"];
        configuration.HTTPMaximumConnectionsPerHost = files.count;
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        
        NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            if (error) {
                result(responseObject,api_progress,ApiStatusError);
            } else {
                result(responseObject,api_progress,ApiStatusSuccess);
            }
        }];
        
        [uploadTask resume];
        
#ifndef TARGET_IPHONE_SIMULATOR
    }
#endif
}


-(void)downloadFile:(NSDictionary *)parameters FileUrl:(NSString *)file_url Result:(void (^)(id result_data, ApiStatus result_status))result Progress:(void (^)(CGFloat progress))progress {
    
#ifndef TARGET_IPHONE_SIMULATOR
    if (![NetworkHelper isNetWorkReachable])
    {
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedString(@"Please check your network connection is correct", @"请检查您的网络连接是否正确") forKey:NSLocalizedDescriptionKey];
        NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:eJsonNil userInfo:userInfo];
        result(error,ApiStatusNetworkNotReachable);
        
    } else {
#endif
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"file_down_identifer"];
        configuration.HTTPMaximumConnectionsPerHost = 5;
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        
        NSURL *URL = [NSURL URLWithString:file_url];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
        
        NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
            
            NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
            
            return [documentsDirectoryURL URLByAppendingPathComponent:[NSString stringWithFormat:@"DownloadFile/%@",[response suggestedFilename]]];
            
        } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
            
            if (error) {
                result(filePath,ApiStatusError);
            } else {
                result(filePath,ApiStatusSuccess);
            }
        }];
        
        [downloadTask resume];
       
#ifndef TARGET_IPHONE_SIMULATOR
    }
#endif
}

-(void)apiPost:(NSString *)function Parameters:(NSDictionary *)parameters Result:(void (^)(ApiStatus result_status, NSString *api))result {
    
    ApiEnum api = [NetworkHelper apiEnumWithFunction:function];
    
#ifndef TARGET_IPHONE_SIMULATOR
    if (![NetworkHelper isNetWorkReachable])
    {
        NSArray *modelArr = [[CoreDataStorageController sharedModel] selectElementFromEntity:[ENTITY_NAMES objectForKey:@(api)] PredicateFromat:nil SortKey:nil Limit:0 Ascending:YES];
        [self writeLog:@{@"time":[NSDate date],@"network":@"bad"}];
        result(modelArr,ApiStatusNetworkNotReachable,function);
    } else {
#endif
//        [self.requestSerializer setValue:@"" forHTTPHeaderField:@""];
        [self POST:function parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSError *error = nil;
            id json = @[];
            
            if ([responseObject isKindOfClass:[NSArray class]] ||
                [responseObject isKindOfClass:[NSDictionary class]] ||
                [responseObject isKindOfClass:[NSString class]]) {
                json = responseObject;
            }
            else {
                json = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
            }
            
            NSNumber *errorInfo = json[ERROR];
            
            if (json==nil)
            {
                [self writeLog:@{@"time":[NSDate date],@"response error":@"nil"}];
                result(ApiStatusError,function);
            }
            else if ([json isEqual:[NSNull null]])
            {
                [self writeLog:@{@"time":[NSDate date],@"response error":@"NULL"}];
                result(ApiStatusError,function);
            }
            else if (0 != errorInfo.integerValue) {
                [self writeLog:@{@"time":[NSDate date],@"api error":errorInfo}];
                result(ApiStatusError,function);
            }
            else
            {
                @try {
                    NSArray *Data = json[DATA];
                    
                    if (api == ApiEnumNone) {
                        [self writeLog:@{@"time":[NSDate date],@"api":@"ApiEnumNone"}];
                        result(ApiStatusError,function);
                    }
                    else {
                        [[CoreDataStorageController sharedModel] removeAllElements:[ENTITY_NAMES objectForKey:@(api)]];
                        [Data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                            NSDictionary *modelDic = (NSDictionary *)obj;
                            [JSONHelper jsonToModel:modelDic Api:api Idx:idx ImageURL:@""];
                        }];
                        [[CoreDataStorageController sharedModel] saveContext];
                    }
                }
                @catch (NSException *exception) {
                    [self writeLog:@{@"time":[NSDate date],@"exception":exception.reason}];
                    result(ApiStatusException,function);
                }
                @finally {
                    [self writeLog:@{@"time":[NSDate date],@"api":[ENTITY_NAMES objectForKey:@(api)]}];
                    result(ApiStatusSuccess,function);
                }
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self writeLog:@{@"time":[NSDate date],@"task":task.taskDescription,@"error":error.description}];
            result(ApiStatusFail,function);
            
        }];
#ifndef TARGET_IPHONE_SIMULATOR
    }
#endif
}

-(void)apiGet:(NSString *)function Parameters:(NSDictionary *)parameters Result:(void (^)(ApiStatus result_status, NSString *api))result {
    ApiEnum api = [NetworkHelper apiEnumWithFunction:function];
    
#ifndef TARGET_IPHONE_SIMULATOR
    if (![NetworkHelper isNetWorkReachable])
    {
        [self writeLog:@{@"time":[NSDate date],@"network":@"bad"}];
        result(ApiStatusNetworkNotReachable,function);
    } else {
#endif
        [self GET:function parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            {
                
                NSError *error = nil;
                id json = @[];
                
                if ([responseObject isKindOfClass:[NSArray class]] ||
                    [responseObject isKindOfClass:[NSDictionary class]] ||
                    [responseObject isKindOfClass:[NSString class]]) {
                    json = responseObject;
                }
                else {
                    json = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
                }
                
                NSNumber *errorInfo = json[ERROR];
                
                if (json==nil)
                {
                    [self writeLog:@{@"time":[NSDate date],@"response error":@"nil"}];
                    result(ApiStatusError,function);
                }
                else if ([json isEqual:[NSNull null]])
                {
                    [self writeLog:@{@"time":[NSDate date],@"response error":@"NULL"}];
                    result(ApiStatusError,function);
                }
                else if (0 != errorInfo.integerValue) {
                    [self writeLog:@{@"time":[NSDate date],@"api error":errorInfo}];
                    result(ApiStatusError,function);
                }
                else
                {
                    @try {
                        NSArray *Data = json[DATA];
                        
                        if (api == ApiEnumNone) {
                            [self writeLog:@{@"time":[NSDate date],@"api":@"ApiEnumNone"}];
                            result(ApiStatusError,function);
                        }
                        else {
                            [[CoreDataStorageController sharedModel] removeAllElements:[ENTITY_NAMES objectForKey:@(api)]];
                            [Data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                                NSDictionary *modelDic = (NSDictionary *)obj;
                                [JSONHelper jsonToModel:modelDic Api:api Idx:idx ImageURL:@""];
                            }];
                            [[CoreDataStorageController sharedModel] saveContext];
                        }
                    }
                    @catch (NSException *exception) {
                        [self writeLog:@{@"time":[NSDate date],@"exception":exception.reason}];
                        result(ApiStatusException,function);
                    }
                    @finally {
                        [self writeLog:@{@"time":[NSDate date],@"api":[ENTITY_NAMES objectForKey:@(api)]}];
                        result(ApiStatusSuccess,function);
                    }
                }
                
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self writeLog:@{@"time":[NSDate date],@"task":task.taskDescription,@"error":error.description}];
            result(ApiStatusFail,function);
        }];
#ifndef TARGET_IPHONE_SIMULATOR
    }
#endif
}

-(void)apiAuthorization {
#ifndef TARGET_IPHONE_SIMULATOR
    if (![NetworkHelper isNetWorkReachable])
    {
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedString(@"Please check your network connection is correct", @"请检查您的网络连接是否正确") forKey:NSLocalizedDescriptionKey];
        NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:eJsonNil userInfo:userInfo];
        result(error,ApiStatusNetworkNotReachable,@"Authorization");
    } else {
#endif
        NSURL *url = [NSURL URLWithString:AFAppDotNetAPIAuthorizationURLString];
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
        NSString *basicAuthUsername = @"admin";
        NSString *basicAuthPassword = @"1234";
        NSData *authorizationData = [[NSString stringWithFormat:@"%@:%@",basicAuthUsername,basicAuthPassword] dataUsingEncoding:NSASCIIStringEncoding];
        NSString *authorizationStr = [NSString stringWithFormat:@"Basic %@",[authorizationData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]];
        [request setHTTPMethod:@"POST"];
        [request addValue:authorizationStr forHTTPHeaderField:@"Authorization"];
        [request addValue:@"*/*" forHTTPHeaderField:@"Accept"];
        
        NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        NSURLSessionDataTask *authorization = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            if (error) {
                [self apiAuthorization];
            }
            else {
                NSError *jsonError = nil;
                id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
                _access_token = [[json valueForKey:@"data"] valueForKey:@"access_token"];
#ifdef DEBUG
                NSLog(@"%@",_access_token);
#endif
            }
        }];
        [authorization resume];
#ifndef TARGET_IPHONE_SIMULATOR
    }
#endif
}

-(void)writeLog:(id)info {
#ifdef DEBUG
    [self.logArr addObject:info];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];
    if (!docDir) {
        NSLog(@"Documents is lose!");
    }
    NSString *filePath = [docDir stringByAppendingPathComponent:@"log.plist"];
    NSMutableArray *oldLogArr = [NSMutableArray arrayWithContentsOfFile:filePath];
    if (nil != oldLogArr && 0 != oldLogArr.count) {
        [self.logArr addObjectsFromArray:oldLogArr];
    }
    [self.logArr writeToFile:filePath atomically:YES];
#endif
}

@end
